﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Test
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Brush penBrush;
        private double penSize;
        private string curFigure;
        private Point mousePos;
        private Line curLine;
        private Ellipse curEllips;
        private Selector curSelector;

        public MainWindow()
        {
            curSelector = null;
            curFigure = "Pen";
            penBrush = new SolidColorBrush(Colors.Black);
            penSize = 1.0;
            InitializeComponent();
        }

        private void ComboBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
        {
            ComboBoxItem typeItem = (ComboBoxItem)((ComboBox)sender).SelectedItem;
            if (typeItem.Content == null)
                return;
            string selected = typeItem.Content.ToString();
            penSize = double.Parse(selected.Split(' ')[0]);
        }

        private void Rectangle_MouseDown_1(object sender, MouseButtonEventArgs e)
        {
            penBrush = ((Rectangle)sender).Fill;
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            curFigure = "Pen";
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            curFigure = "Line";
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            curFigure = "Ellipse";
        }

        private void MyCanvas_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ButtonState == MouseButtonState.Pressed)
                mousePos = e.GetPosition(MyCanvas);
            else
                return;
            if (MyCanvas.Children.Contains(curSelector))
                MyCanvas.Children.Remove(curSelector);
            if (curFigure == "Pen")
            {
                Ellipse elipse = new Ellipse();
                elipse.Height = penSize;
                elipse.Width = penSize;
                Canvas.SetLeft(elipse, mousePos.X - penSize / 2);
                Canvas.SetTop(elipse, mousePos.Y - penSize / 2);
                MyCanvas.Children.Add(elipse);
            }
            else if (curFigure == "Line")
            {
                curLine = new Line();

                curLine.Stroke = penBrush;
                curLine.X1 = mousePos.X;
                curLine.Y1 = mousePos.Y;
                curLine.X2 = mousePos.X;
                curLine.Y2 = mousePos.Y;

                curLine.StrokeThickness = penSize;
                //curLine.StrokeDashArray = new DoubleCollection() { 2, 0.5 ,2};
                //curLine.StrokeDashArray = new DoubleCollection() { 2, 0.5, 2, 0.5, 2};
                curLine.StrokeDashArray = new DoubleCollection() { 2,2 };

                MyCanvas.Children.Add(curLine);
            }
            else if (curFigure == "Ellipse")
            {
                curEllips = new Ellipse();
                curEllips.Stroke = penBrush;
                curEllips.StrokeThickness = penSize;
                curEllips.StrokeDashArray = new DoubleCollection() { 2, 2 };
                Canvas.SetLeft(curEllips, mousePos.X);
                Canvas.SetTop(curEllips, mousePos.Y);
                MyCanvas.Children.Add(curEllips);
            }
        }

        private void MyCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton != MouseButtonState.Pressed)
                return;
            if (curFigure == "Pen")
            {
                Line line = new Line();

                line.Stroke = penBrush;
                line.X1 = mousePos.X;
                line.Y1 = mousePos.Y;
                line.X2 = e.GetPosition(MyCanvas).X;
                line.Y2 = e.GetPosition(MyCanvas).Y;

                line.StrokeThickness = penSize;

                mousePos = e.GetPosition(MyCanvas);

                Ellipse elipse = new Ellipse();
                elipse.Fill = penBrush;
                elipse.Height = penSize;
                elipse.Width = penSize;
                Canvas.SetLeft(elipse, mousePos.X - penSize / 2);
                Canvas.SetTop(elipse, mousePos.Y - penSize / 2);
                MyCanvas.Children.Add(elipse);

                MyCanvas.Children.Add(line);

            }
            else if (curFigure == "Line")
            {

                curLine.X2 = e.GetPosition(MyCanvas).X;
                curLine.Y2 = e.GetPosition(MyCanvas).Y;

            }
            else if (curFigure == "Ellipse")
            {
                double x = Math.Min(e.GetPosition(MyCanvas).X, mousePos.X);
                var y = Math.Min(e.GetPosition(MyCanvas).Y, mousePos.Y);

                var w = Math.Max(e.GetPosition(MyCanvas).X, mousePos.X) - x;
                var h = Math.Max(e.GetPosition(MyCanvas).Y, mousePos.Y) - y;

                curEllips.Width = w;
                curEllips.Height = h;

                Canvas.SetLeft(curEllips, x);
                Canvas.SetTop(curEllips, y);
            }
        }

        private void Button_Click_4(object sender, RoutedEventArgs e)
        {
            MyCanvas.Children.Clear();
        }

        private void MyCanvas_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (curFigure == "Ellipse")
            {
                curSelector = new Selector(curEllips, MyCanvas);

                MyCanvas.Children.Add(curSelector);
            }
            curLine = null;
        }

        private void Open_Click_1(object sender, RoutedEventArgs e)
        {
            // Create OpenFileDialog
            Microsoft.Win32.OpenFileDialog openFileDlg = new Microsoft.Win32.OpenFileDialog();

            // Set filter for file extension and default file extension
            openFileDlg.DefaultExt = ".jpg";
            openFileDlg.Filter = "Image Files (*.bmp, *.jpg, *.png, *.chtp)|*.bmp;*.jpg;*.png;*.chtp";

            // Display OpenFileDialog by calling ShowDialog method
            Nullable<bool> result = openFileDlg.ShowDialog();

            // Get the selected file name and display in a TextBox
            if (result == true)
            {
                // Open document
                string filename = openFileDlg.FileName;
                string ext = System.IO.Path.GetExtension(filename);

                if (ext == ".jpg" || ext == ".bmp" || ext == ".png")
                {
                    // Open a Stream and decode a PNG image
                    System.IO.Stream imageStreamSource = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
                    BitmapDecoder decoder = null;
                    switch (ext)
                    {
                        case ".jpg":
                            decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                            break;
                        case ".bmp":
                            decoder = new BmpBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                            break;
                        case ".png":
                            decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                            break;
                    }
                    
                    BitmapSource bitmapSource = decoder.Frames[0];

                    // Draw the Image
                    Image myImage = new Image();
                    myImage.Source = bitmapSource;
                    myImage.Stretch = Stretch.None;
                    myImage.Margin = new Thickness(20);
                    MyCanvas.Children.Add(myImage);
                }
                else  //chtp
                {
                    using (System.IO.FileStream fs = System.IO.File.OpenRead(filename))
                    {
                        byte[] b = new byte[fs.Length];
                        UTF8Encoding temp = new UTF8Encoding(true);
                        fs.Read(b, 0, b.Length);
                        string content = temp.GetString(b);
                        System.IO.StringReader stringReader = new System.IO.StringReader(content);
                        System.Xml.XmlReader xmlReader = System.Xml.XmlReader.Create(stringReader);
                        Canvas loaded = (Canvas)System.Windows.Markup.XamlReader.Load(xmlReader);
                        MyCanvas.Children.Clear();
                        UIElement[] arr = new UIElement[loaded.Children.Count];
                        loaded.Children.CopyTo(arr, 0);
                        loaded.Children.Clear();
                        foreach (UIElement elem in arr)
                        {
                            MyCanvas.Children.Add(elem);
                        }
                    }
                }
            }
        }

        private void Save_Click_1(object sender, RoutedEventArgs e)
        {
            // Configure save file dialog box
            Microsoft.Win32.SaveFileDialog saveFileDlg = new Microsoft.Win32.SaveFileDialog();
            saveFileDlg.FileName = "NewImage"; // Default file name
            saveFileDlg.DefaultExt = ".chtp"; // Default file extension
            saveFileDlg.Filter = " JPG(*.jpg)|*.jpg|BMP (*.bmp)|*.bmp| PNG(*.png)|*.png | Specific program format(*.chtp)|*.chtp"; // Filter files by extension

            // Show save file dialog box
            Nullable<bool> result = saveFileDlg.ShowDialog();

            // Process save file dialog box results
            if (result == true)
            {
                // Save document
                string filename = saveFileDlg.FileName;
                string ext = System.IO.Path.GetExtension(filename);

                if (ext == ".jpg" || ext == ".bmp" || ext == ".png")
                {
                    // Save current canvas transform
                    Transform transform = MyCanvas.LayoutTransform;
                    // reset current transform (in case it is scaled or rotated)
                    MyCanvas.LayoutTransform = null;

                    RenderTargetBitmap rtb = new RenderTargetBitmap((int)MyCanvas.RenderSize.Width,
                    (int)MyCanvas.RenderSize.Height, 96d, 96d, System.Windows.Media.PixelFormats.Default);
                    rtb.Render(MyCanvas);

                    BitmapEncoder encoder = new JpegBitmapEncoder();
                    switch (ext)
                    {
                        case ".jpg":
                            encoder = new JpegBitmapEncoder();
                            break;
                        case ".bmp":
                            encoder = new BmpBitmapEncoder();
                            break;
                        case ".png":
                            encoder = new PngBitmapEncoder();
                            break;
                    }
                    encoder.Frames.Add(BitmapFrame.Create(rtb));

                    using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Create))
                    {
                        encoder.Save(fs);
                        fs.Close();
                    }
                    MyCanvas.LayoutTransform = transform;
                }
                else //chtp
                {
                    string savedCanvas = System.Windows.Markup.XamlWriter.Save(MyCanvas);
                    using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Create))
                    {
                        byte[] info = new UTF8Encoding(true).GetBytes(savedCanvas);
                        fs.Write(info, 0, info.Length);
                        fs.Close();
                    }
                }
            }
        }

    }
}
